package service

import (
	"encoding/json"
	"errors"
	"fmt"
	"gin_wuwen_back/dao"
	"gin_wuwen_back/model"
	"gin_wuwen_back/param"
	"gin_wuwen_back/tool"
	"github.com/aliyun/alibaba-cloud-sdk-go/services/dysmsapi"
	"strconv"

	"math/rand"
	"time"
)

type Service_func struct {
}
var Fuc *Service_func
//发送验证码具体的处理逻辑
func (tmp *Service_func) SendCode(phone string) bool {

	/*
		发送验证码具体的处理逻辑
	*/
	//1.获取一个随机的验证码
	code := fmt.Sprintf("%04v", rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(10000))
	//调用阿里云的api来完成发送
	config := tool.Getconfig().Sms

	client, err := dysmsapi.NewClientWithAccessKey(config.Region_id, config.Appkey, config.Appsecret)

	if err != nil {
		panic(err)
		return false
	}
	request := dysmsapi.CreateSendSmsRequest()
	request.Scheme = "https"
	request.SignName = config.Sign_name
	request.TemplateCode = config.Templatecode
	request.PhoneNumbers = phone
	par, err := json.Marshal(map[string]interface{}{
		"code": code,
	})

	request.TemplateParam = string(par)

	response, err := client.SendSms(request)
	fmt.Println(response)
	if err != nil {
		panic(err.Error())
		return false

	}

	//如果发送成功我们就返回发送成功的代码
	if response.Code == "ok" {
		//将验证码存入到数据库当中
		Smscode := model.SmsCode{Phone: phone, Code: code, BizId: response.BizId, CreateTime: time.Now().Unix()}
		//和数据库存储相关的逻辑我们再建立一层封装
		memberdao := dao.Memberdao{tool.Dbengin} //实例化对象
		result := memberdao.InsertCode(Smscode)
		return result > 0

		return true
	}

	return false

}

func (tmp *Service_func) SmsLogin(loginparam param.LoginSmsParam) *model.Member {
	/**
	 * @Description://手机号+验证码登陆的具体逻辑
	 * @receiver tmp
	 * @param loginparam 从post请求中获取的参数，传入这里
	 * @return *model.Member 返回我们查询出来对象的地址
	 */
	//todo
	//1.获取手机号和验证码

	//2.验证手机号和验证码是否正确
	md := dao.Memberdao{tool.Dbengin}
	sms := md.VaSmsCode(loginparam.Phone, loginparam.Code)
	if sms.Id == 0 {
		return nil
	}
	//3.根据手机号去member表中查询数据,
	member := md.QueryByPhone(loginparam.Phone)
	if member.Id != 0 {
		return member

	}
	//4.如果没有记录，那我们就当做是注册，我们就在数据表中创建一条新的记录
	//我们用户通过手机号注册的
	//如果没有查询到member信息那么就是第一次登陆，
	//我们要将他的信息存入member表中
	//在上一步中如果他是已经注册过了的那么我们就将他的信息返回，如果是
	//新用户我们就做一下注册
	user := model.Member{}
	user.UserName = loginparam.Phone
	user.Mobile = loginparam.Phone
	user.RegisterTime = time.Now().Unix()

	user.Id = md.InsetMember(user)

	return &user

}

/*
  @Description: 实现用户登陆的逻辑
  @receiver tmp
  @param name 传递过来的用户名
  @param password 传递过来的密码
*/
func (tmp *Service_func) LoginBypass(name string, password string) (*model.Member,error) {
	//分几种情况来进行考虑
	//用户已经注册了，我们查询出来信息进行返回
	md := dao.Memberdao{tool.Dbengin}
	member := md.QueryLoginByPass(name, password)
	if member.Id != 0 {
		return member,nil

	}else {
		err1:=errors.New("登录失败")
		return nil, err1
	}

	////用户没有注册过，我们直接进行创建用户
	//user := model.Member{}
	//user.UserName = name
	//user.Password = tool.EncoderSha256(password)
	//user.RegisterTime = time.Now().Unix()
	//result := md.InsetMember(user)
	//user.Id = result
	//return &user

}

/*
  @Description: 用户上传头像的具体逻辑层
  @receiver tmp
  @param id 要上传头像用户的id
  @param filename 要上传的头像的文件名
  @return string 返回这张头像图片的存储地址
*/
func (tmp *Service_func) UploadAvator(id int64, filename string) string {

	md := dao.Memberdao{tool.Dbengin}
	result := md.UpdataMember(id, filename)
	if result == 0 {
		fmt.Println("更新失败")
		return ""
	}

	return filename

}

/*
  @Description: 根据userId来进行查询我们的用户信息
  @receiver tmp
  @param userId 要查询的用户的id
  @return *model.Member 查询到的用户的对象
*/
func (tmp *Service_func) GetUserinfo(userId string) *model.Member {
	id, err := strconv.Atoi(userId)
	if err != nil {
		return nil
	}
	//下面我们就进入数据库层的编写
	memberDao := dao.Memberdao{tool.Dbengin}
	return memberDao.QueryMemberById(int64(id))

}
